/**
  ******************************************************************************
  * @author     Chris
  * @since      2024/6/18 16:18
  *
  * @file       pd_exti.c
  * @brief      EXTI hardware driver.
  *
  * @note       This file contains the hardware driver for the EXTI.
  *
  * @warning    None.
  ******************************************************************************
  * Change Logs:
  *   Date          Author       Notes
  *   2024/6/18     Chris        the first version
  *
  ******************************************************************************
  */


#include <pd_exti.h>
#include <stm32f4xx_ll_bus.h>
#include <stm32f4xx_ll_exti.h>
#include <stm32f4xx_ll_gpio.h>
#include <stm32f4xx_ll_system.h>

static void ExtIR_init_(const ExtIR *this, IRQn_Type irQnType, uint32_t PreemptPriority, uint32_t SubPriority) {
    GPIO_init(this->gpio);

    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);

    LL_SYSCFG_SetEXTISource(this->Port, this->Line);

    LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
    EXTI_InitStruct.Line_0_31   = this->Line_0_31;
    EXTI_InitStruct.LineCommand = this->LineCommand;
    EXTI_InitStruct.Mode        = this->Mode;
    EXTI_InitStruct.Trigger     = this->Trigger;
    LL_EXTI_Init(&EXTI_InitStruct);

    // NVIC also can be init in main.c
    NVIC_SetPriority(irQnType, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), PreemptPriority, SubPriority));
    NVIC_EnableIRQ(irQnType);
}

void ExtIR_constructor(ExtIR *this, GPIO *gpio, uint32_t Line_0_31, uint32_t Port, uint32_t Line) {
    gpio->Mode = LL_GPIO_MODE_INPUT;

    static struct ExtIRVtbl vtbl = {
        .init = &ExtIR_init_,
    };

    this->vptr = &vtbl;

    this->gpio = gpio;
    this->Port = Port;
    this->Line = Line;

    this->Line_0_31   = Line_0_31;
    this->LineCommand = ENABLE;
    this->Mode        = LL_EXTI_MODE_IT;
    this->Trigger     = LL_EXTI_TRIGGER_RISING;
}
